/*|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|
  |                   Métodos Numéricos II                   |
  |           Autovalores e Autovetores - Tarefa 7           |
  |                     Método de Jacobi                     |
  |__________________________________________________________|*/

// É Linux ou é Windows?
#ifdef linux      // Sistema Operacional: Linux.
    #define sistema_operacional 0
#else
    #ifdef _WIN32 // Sistema Operacional: Windows.
        #define sistema_operacional 1
    #endif
#endif
// Vixe! Não é nenhum dos 2...
#ifndef sistema_operacional
    #error Sistema Operacional desconhecido!!! So rodo no Linux ou no Windows!!!
#endif

/*** LIXUX - INCLUDES E DEFINES ***/
#if (sistema_operacional == 0)
    #include "Extras/fuba_linux.h"
#endif

/*** WINDOWS - INCLUDES E DEFINES ***/
#if (sistema_operacional == 1)
    #include "Extras/fuba_win.h"
#endif

/*** DEFINES do programa ***/
// NADA!

/*** INCLUDES do programa ***/
#include <iostream>

// Classes:
#include "Classes/matriz.h"
#include "Classes/jacobi.h"
using namespace std;

int main(void) // PRINCIPAL //
{
    // Variáveis do MAIN:
    char escolha = '\0';
    int matriz_ordem;
    double matriz_valor, erro=0.0001;
    matriz M, A_valores, A_vetores;
    jacobi JAC;

//************************************
// Matriz dada na questão:
M.alocar(3,3);
M.set_aij(0,0,4);
M.set_aij(0,1,2);
M.set_aij(0,2,1);
M.set_aij(1,0,2);
M.set_aij(1,1,3);
M.set_aij(1,2,2);
M.set_aij(2,0,1);
M.set_aij(2,1,2);
M.set_aij(2,2,5);
/***********************************/

/************************************
// Exemplo da apsotila:
M.alocar(4,4);
M.set_aij(0,0,1.36);
M.set_aij(0,1,-0.48);
M.set_aij(0,2,-1);
M.set_aij(0,3,0);
M.set_aij(1,0,-0.48);
M.set_aij(1,1,1.64);
M.set_aij(1,2,0);
M.set_aij(1,3,0);
M.set_aij(2,0,-1);
M.set_aij(2,1,0);
M.set_aij(2,2,1.36);
M.set_aij(2,3,0.48);
M.set_aij(3,0,0);
M.set_aij(3,1,0);
M.set_aij(3,2,0.48);
M.set_aij(3,3,1.64);
/***********************************/

    do{// MENU PRINCIPAL //
        limpar_tela();
        cout <<"#=============================================================#"<<endl;
        cout <<"#            Autovalores e Autovetores - Tarefa 7             #"<<endl;
		cout <<"#                      Metodo de Jacobi                       #"<<endl;
        cout <<"#=============================================================#"<<endl;
        cout <<"> Erro: "<<erro<<" <"<<endl;
        cout <<"> Escolha:"<<endl;
        cout <<"  (1) Inserir a dimensao da matriz;"<<endl;
        cout <<"  (2) Inserir a matriz;"<<endl;
        cout <<"  (3) Imprimir a matriz;"<<endl;
        cout <<"  (4) Inserir o erro;"<<endl;
        cout <<"  (J) Aplicar o Metodo de de Jacobi;"<<endl;
        cout <<"  (X) Sair do programa."<<endl;
        escolha = ler_tecla();
        switch(escolha)
        {
            case '1': /// Dimensão da matriz ///
            {
                limpar_tela();
                cout <<"+----------------------+"<<endl;
                cout <<"|  Dimensao da matriz  |"<<endl;
                cout <<"+----------------------+"<<endl;
                M.desalocar();
                cout <<"* Digite a ordem da matriz: ";
                cin >> matriz_ordem;
                M.alocar(matriz_ordem,matriz_ordem);
                break;
            }

            case '2': /// Inserir os elementos da matriz ///
            {
                limpar_tela();
                cout <<"+----------------------------------+"<<endl;
                cout <<"|  Inserir os elementos da matriz  |"<<endl;
                cout <<"+----------------------------------+"<<endl;
                cout <<"> Matriz \"M\": "<<M.get_linhas()<<" x "<<M.get_colunas()<<" -> "<<(M.get_linhas() * M.get_colunas())<<" elementos."<<endl;
                for(int i=0 ; i<(M.get_linhas()) ; i++)
                {
                    for(int j=0 ; j<(M.get_colunas()) ; j++)
                    {
                        cout <<"* Digite o elemento M["<<i<<","<<j<<"]: ";
                        cin >> matriz_valor;
                        M.set_aij(i,j,matriz_valor);
                    }
                }
                break;
            }

            case '3': /// Imprimir a matriz ///
            {
                limpar_tela();
                cout <<"+---------------------+"<<endl;
                cout <<"|  Imprimir a matriz  |"<<endl;
                cout <<"+---------------------+"<<endl;
                cout <<"* Matriz \"M\":"<<endl;
                M.imprimir();
                pausar();
                break;
            }

            case '4': /// Inserir o erro ///
            {
                limpar_tela();
                cout <<"+------------------+"<<endl;
                cout <<"|  Inserir o erro  |"<<endl;
                cout <<"+------------------+"<<endl;
                cout <<"* Digite o valor do erro: ";
                cin >> erro;
                break;
            }

            case 'J': /// Metodo de Jacobi ///
            {
                limpar_tela();
                cout <<"+--------------------+"<<endl;
                cout <<"|  Metodo de Jacobi  |"<<endl;
                cout <<"+--------------------+"<<endl;
                cout <<"* Matriz \"M\":"<<endl;
                M.imprimir();
                if (JAC.diagonalizar(&M,erro,&A_valores,&A_vetores))
                {
                    cout <<"\n* Autovalores e Autovetores:"<<endl;
                    JAC.exibir_autovalor_autovetor(&A_valores,&A_vetores);
                }
                pausar();
                break;
            }
        }// fim do "switch(escolha)" //
      }while(escolha!='X');// fim do "MENU PRINCIPAL" //
    return(0);
}
